/*    Copyright 2010 Tobias Marschall
 *
 *    This file is part of MoSDi.
 *
 *    MoSDi is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    MoSDi is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with MoSDi.  If not, see <http://www.gnu.org/licenses/>.
 */

package mosdi.discovery;

import mosdi.index.SuffixTree;

public interface ObjectiveFunction {
	/** Initialization method called once before search starts. NO other methods
	 *  MUST be called before initialize().
	 *  
	 *  @param searchState Through this object information about the current search
	 *                     can be obtained. 
	 */
	public void initialize(MotifFinder.SearchState searchState);

	/** Called in the course of the iteration over pattern space whenever
	 *  the pattern has changed.
	 *  
	 *  @param newCharacter Gives the new character at leftmostChangedPosition, i.e.
	 *                      after the call, a prefix of length leftmostChangedPosition+1
	 *                      is known.
	 */
	public void updatePattern(int newCharacter, int leftmostChangedPosition);

	/** Given the indices of suffix tree nodes that correspond to a prefix of 
	 *  the pattern, compute a lower bound on the patterns p-value. */
	public double pValueLowerBound(int prefixLength, int[] nodes);
	
	/** Calculate score and p-value for a pattern during motif discovery. This method 
	 *  may decide that the given pattern is not interesting and skip its evaluation; 
	 *  in this case, an empty score as given by "new ScoreAndPValue()" is returned.
	 *  
	 *  BEFORE this method may be called (1) initialize() must have been called and
	 *  (2) the investigated pattern must have been set using updatePattern().
	 *  
	 *  For evaluating a single pattern without this preparation, use staticEvaluate.
	 *  
	 * @param pValueThreshold If pattern's p-value is larger than pValueThreshold, this 
	 *                        method is allowed (but not required) to abort computation 
	 *                        and return null to save time.
	 */
	public ScoreAndPValue evaluate(int[] nodes, double pValueThreshold);
	
	/** Pattern evaluation without the need to use initialize() and updatePattern(). Returns
	 *  the same score as evaluate(), but is (possibly) slower. If the pvalue is larger than
	 *  the given threshold, null is returned. 
	 */
	public ScoreAndPValue staticEvaluate(int[] pattern, boolean considerReverse, SuffixTree suffixTree, double pValueThreshold);
	
	/** Returns a name for this objective. */
	public String getName();
	
}
